package com.copa.test;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.copa.domain.BaseEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @author copa
 * @createDate 2021-01-06 12:29
 * @function 自动生成表
 */
@Slf4j
public class CodeGenerator {

    private final static String URL = "jdbc:p6spy:mysql://127.0.0.1:3306/medicine-mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false";

    private final static String USERNAME = "root";

    private final static String PASSWORD = "123456";

    private final static String DRIVER_NAME = "com.p6spy.engine.spy.P6SpyDriver";

    private final static String MUDULE_NAME = "system";

    private final static String PROJECT_PATH = System.getProperty("user.dir");


    public static void main(String[] args) {

        // 全局配置
        GlobalConfig config = getGlobalConfig();

        // 数据源配置
        DataSourceConfig dataSourceConfig = getDataSourceConfig();

        // 策略配置
        StrategyConfig strategyConfig = getStrategyConfig();

        // 包名策略配置
        PackageConfig packageConfig = getPackageConfig();

        // 配置模板
        TemplateConfig templateConfig = getTemplateConfig();

        // 自定义模版配置
        InjectionConfig injectionConfig = getInjectionConfig();

        // 整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setTemplate(templateConfig)
                .setCfg(injectionConfig);

        // 执行
        autoGenerator.execute();

    }

    /**
     * 自定义模版配置
     * @return
     */
    private static InjectionConfig getInjectionConfig() {
        InjectionConfig injectionConfig = new InjectionConfig() {
            //自定义属性注入:abc
            //在.ftl(或者是.vm)模板中，通过${cfg.abc}获取属性
            @Override
            public void initMap() {

            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();

        // 自定义配置会被优先输出，设置Entity
        focList.add(new FileOutConfig("templates/entity.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //修改Entity文件
                return PROJECT_PATH + "/medicine-mall-admin/src/main/java/com/copa/module/" + MUDULE_NAME
                        + "/domain/entity/" + tableInfo.getEntityName() + "Entity" + StringPool.DOT_JAVA;
            }
        });

        // 自定义配置会被优先输出，设置Mapper
        focList.add(new FileOutConfig("templates/mapper.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //修改Mapper文件
                return PROJECT_PATH + "/medicine-mall-admin/src/main/java/com/copa/module/" + MUDULE_NAME
                        + "/mapper/" + tableInfo.getEntityName() + "Dao" + StringPool.DOT_JAVA;
            }
        });

        // 自定义配置会被优先输出，设置xml
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //修改xml文件
                return PROJECT_PATH + "/medicine-mall-admin/src/main/resources/mapper/" + MUDULE_NAME
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        injectionConfig.setFileOutConfigList(focList);
        return injectionConfig;
    }

    /**
     * 配置模板
     * @return
     */
    private static TemplateConfig getTemplateConfig() {
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setController(null)
                .setEntityKt(null)
                .setService(null)
                .setServiceImpl(null)
                .setEntity(null)
                .setMapper(null)
                .setXml(null);
        return templateConfig;
    }

    private static PackageConfig getPackageConfig() {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("")
                .setMapper("com.copa.module." + MUDULE_NAME + ".mapper")
                .setEntity("com.copa.module." + MUDULE_NAME + ".domain.entity")
                .setXml("resources.mapper." + MUDULE_NAME);
        return packageConfig;
    }

    /**
     * 策略配置
     * @return
     */
    private static StrategyConfig getStrategyConfig() {
        Scanner in = new Scanner(System.in);

        StrategyConfig strategyConfig = new StrategyConfig();
        // 全局大写命名
        strategyConfig.setCapitalMode(true)
                // 数据库映射好的命名策略
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setSuperEntityClass(BaseEntity.class)
                .setEntityLombokModel(true)
                .setEntityBuilderModel(true)
                .setEntityColumnConstant(true)
                .setEntitySerialVersionUID(true)
                .setEntityTableFieldAnnotationEnable(true)
                .setSuperEntityColumns("id","create_time","update_time")
                .setEntitySerialVersionUID(true)
                .setEntityBuilderModel(true)
                // 生成的表
                .setTablePrefix("t_")
                .setInclude(scanner("请输入表名，多个英文逗号分割").split(","));
                //.setInclude("r_role");
        return strategyConfig;
    }

    /**
     * 数据源配置
     * @return
     */
    private static DataSourceConfig getDataSourceConfig() {
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)
                .setDriverName(DRIVER_NAME)
                .setUrl(URL)
                .setUsername(USERNAME)
                .setPassword(PASSWORD);
        return dataSourceConfig;
    }

    /**
     * 全局配置
     * @return
     */
    private static GlobalConfig getGlobalConfig() {

        GlobalConfig config = new GlobalConfig();
        // 是否支持AR模式
        config.setActiveRecord(true)
                // 作者
                .setAuthor("copa")
                // 生成路径
                .setOutputDir(PROJECT_PATH + "/src/main")
                // 文件覆盖
                .setFileOverride(true)
                .setIdType(IdType.AUTO)
                //.setServiceName("%sService")
                .setBaseResultMap(true)
                .setSwagger2(true)
                .setBaseColumnList(true);
        return config;
    }

    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append(tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }
}